package com.bovink.util.library;

import android.support.v7.widget.RecyclerView;
import android.view.ViewGroup;

/**
 * PoweredRecyclerView数据适配器
 *
 * @author bovink
 * @since 2016/8/18
 */
public abstract class PoweredAdapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    /**
     * 视图为顶部视图
     */
    private final int TYPE_HEADER = 0;
    /**
     * 视图为子项目视图
     */
    private final int TYPE_ITEM = 1;
    /**
     * 视图为底部视图
     */
    private final int TYPE_FOOTER = 2;
    /**
     * 用来储存顶部视图
     */
    private RecyclerView.ViewHolder header;
    /**
     * 用来储存底部视图
     */
    private PoweredFooterView footer;
    /**
     * RecyclerView是否有顶部
     */
    private boolean hasHeader = false;
    /**
     * RecyclerView是否有底部
     */
    private boolean hasFooter = false;
    /**
     * RecyclerViewItem的容量
     */
    private int count = 0;
    /**
     * 内容物的类
     */
    private Class<?> itemClass;
    /**
     * 是否还有可加载数据
     */
    boolean hasMoreItem = false;

    @Override
    public final RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        RecyclerView.ViewHolder view = null;
        // 头部
        if (viewType == TYPE_HEADER) {
            view = header;
        } else if (viewType == TYPE_ITEM) {
            // 子项目
            VH item = onCreateItemView(parent);
            itemClass = item.getClass();
            view = item;

            // 底部
        } else if (viewType == TYPE_FOOTER) {
            view = footer;
        }
        return view;
    }

    @Override
    public final void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof PoweredFooterView) {

            // 根据是否放还有可加载数据决定footer的提示
            if (hasMoreItem && hasFooter) {
                footer.loading();
            } else if (!hasMoreItem && hasFooter){
                footer.loadEnd();
            }
        } else if (holder != header && itemClass.isInstance(holder)) {
            // 如果有顶部，实际索引0为顶部，1才是item起始
            int realPosition;
            if (hasHeader) {
                realPosition = position - 1;
            } else {
                realPosition = position;
            }
            VH item = (VH) holder;
            onBindItemView(item, realPosition);
        }
    }

    @Override
    public final int getItemCount() {
        count = getCount();
        int extra = 0;
        // 有顶部则count+1
        if (hasHeader) {
            extra += 1;
        }
        // 有底部且显示则count+1
        if (hasFooter) {
            extra += 1;
        }
        // 包括头部和尾部都显示的话，数据长度应该加2
        return count + extra;
    }

    @Override
    public final int getItemViewType(int position) {
        if (hasHeader && position == 0) {
            return TYPE_HEADER;
        } else if (hasFooter) {
            if (position == count + (hasHeader ? 1 : 0)) {
                return TYPE_FOOTER;
            }
        }
        return TYPE_ITEM;
    }

    /**
     * 设置是否还有数据可以加载
     *
     * @param hasMoreItem flag
     */
    public final void setHasMoreItem(boolean hasMoreItem) {
        this.hasMoreItem = hasMoreItem;
    }

    /**
     * 设置顶部视图
     *
     * @param header 顶部视图
     */
    public final void setHeader(RecyclerView.ViewHolder header) {
        if (header == null) {
            throw new NullPointerException("don't accept a null value");
        }
        this.header = header;
        hasHeader = true;
    }

    /**
     * 设置底部视图
     *
     * @param footer 底部视图
     */
    public final void setFooter(PoweredFooterView footer) {
        if (footer == null) {
            throw new NullPointerException("don't accept a null value");
        }
        this.footer = footer;
        hasFooter = true;
    }

    /**
     * 创建itemView
     *
     * @param parent recyclerView
     * @return itemview
     */
    public abstract VH onCreateItemView(ViewGroup parent);

    /**
     * 给itemView绑定数据
     *
     * @param holder     itemview
     * @param position itemview索引
     */
    public abstract void onBindItemView(VH holder, int position);

    /**
     * itemview的size
     *
     * @return itemview的size
     */
    public abstract int getCount();
}
